// Copyright (C)2012 Johann Duscher. All rights reserved.
//
// This file is part of QwTAPI.
//
// QwTAPI is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// QwTAPI is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with QwTAPI.  If not, see <http://www.gnu.org/licenses/>.

#include "Request.h"

#include "Connection.h"


namespace qwtapi
{

Request::Request(Connection* pConnection)
    : super(pConnection),
      m_requestType(NULL),
      m_requestId(-1),
      m_completeTime(0),
      m_result(-1),
      m_pending(true),
      m_timeout(false)
{
    Q_ASSERT(pConnection);

    m_timeoutTimer.setSingleShot(true);
    connect(&m_timeoutTimer, SIGNAL(timeout()), SLOT(onTimeout()));
}

Request::~Request()
{
    qDebug() << Q_FUNC_INFO << this << m_requestType << m_requestId << toString(m_result) << m_completeTime;
    // If request has been initialized, i.e. added to the Connection's request list, remove it from that list.
    if (m_requestType)
    {
        bool removed = Connection::instance()->removeRequest(m_requestId);
        Q_ASSERT(removed);
        m_requestType = NULL;
        m_requestId = -1;
    }
}

void Request::initialize(Type requestType, LONG requestId, int timeout)
{
    Q_ASSERT(NULL != requestType);
    Q_ASSERT(requestId >= 0);

    m_requestType = requestType;
    m_requestId = requestId;
    m_timeoutTimer.setInterval(timeout);
}

Request::Type Request::getRequestType() const
{
    return m_requestType;
}

LONG Request::getRequestId() const
{
    return m_requestId;
}

HCALL& Request::callHandle()
{
    return m_hCall;
}

const HCALL& Request::callHandle() const
{
    return m_hCall;
}

bool Request::isPending() const
{
    return m_pending;
}

void Request::onRequestComplete(LONG result)
{
    m_result = result;
    m_completeTime = GetTickCount();
    m_pending = false;

    emit requestComplete(this);

    deleteLater();
}

void Request::onTimeout()
{
    m_timeout = true;

    onRequestComplete(m_result);
}

bool Request::isTimeout() const
{
    return !m_pending && !m_completeTime;
}
LONG Request::getResult() const
{
    return m_result;
}

void Request::startTimeoutTimer()
{
    m_timeoutTimer.start();
}

void Request::stopTimeoutTimer()
{
    m_timeoutTimer.stop();
}

}
